<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><link rel="stylesheet" type="text/css" href="style.css" /><script type="text/javascript" src="highlight.js"></script></head><body><pre><span class="hs-comment">{-
(c) The AQUA Project, Glasgow University, 1994-1998

\section[LiberateCase]{Unroll recursion to allow evals to be lifted from a loop}
-}</span><span>
</span><span id="line-6"></span><span>
</span><span id="line-7"></span><span class="hs-pragma">{-# LANGUAGE CPP #-}</span><span>
</span><span id="line-8"></span><span class="hs-keyword">module</span><span> </span><span class="hs-identifier">GHC.Core.Opt.LiberateCase</span><span> </span><span class="hs-special">(</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#liberateCase"><span class="hs-identifier">liberateCase</span></a></span><span> </span><span class="hs-special">)</span><span> </span><span class="hs-keyword">where</span><span class="hs-cpp">

#include &quot;HsVersions.h&quot;
</span><span>
</span><span id="line-12"></span><span class="hs-keyword">import</span><span> </span><span class="annot"><a href="GHC.Prelude.html"><span class="hs-identifier">GHC.Prelude</span></a></span><span>
</span><span id="line-13"></span><span>
</span><span id="line-14"></span><span class="hs-keyword">import</span><span> </span><span class="annot"><a href="GHC.Driver.Session.html"><span class="hs-identifier">GHC.Driver.Session</span></a></span><span>
</span><span id="line-15"></span><span class="hs-keyword">import</span><span> </span><span class="annot"><a href="GHC.Core.html"><span class="hs-identifier">GHC.Core</span></a></span><span>
</span><span id="line-16"></span><span class="hs-keyword">import</span><span> </span><span class="annot"><a href="GHC.Core.Unfold.html"><span class="hs-identifier">GHC.Core.Unfold</span></a></span><span>  </span><span class="hs-special">(</span><span> </span><span class="annot"><a href="GHC.Core.Unfold.html#couldBeSmallEnoughToInline"><span class="hs-identifier">couldBeSmallEnoughToInline</span></a></span><span> </span><span class="hs-special">)</span><span>
</span><span id="line-17"></span><span class="hs-keyword">import</span><span> </span><span class="annot"><a href="GHC.Builtin.Types.html"><span class="hs-identifier">GHC.Builtin.Types</span></a></span><span> </span><span class="hs-special">(</span><span> </span><span class="annot"><a href="GHC.Builtin.Types.html#unitDataConId"><span class="hs-identifier">unitDataConId</span></a></span><span> </span><span class="hs-special">)</span><span>
</span><span id="line-18"></span><span class="hs-keyword">import</span><span> </span><span class="annot"><a href="GHC.Types.Id.html"><span class="hs-identifier">GHC.Types.Id</span></a></span><span>
</span><span id="line-19"></span><span class="hs-keyword">import</span><span> </span><span class="annot"><a href="GHC.Types.Var.Env.html"><span class="hs-identifier">GHC.Types.Var.Env</span></a></span><span>
</span><span id="line-20"></span><span class="hs-keyword">import</span><span> </span><span class="annot"><a href="GHC.Utils.Misc.html"><span class="hs-identifier">GHC.Utils.Misc</span></a></span><span>    </span><span class="hs-special">(</span><span> </span><span class="annot"><a href="GHC.Utils.Misc.html#notNull"><span class="hs-identifier">notNull</span></a></span><span> </span><span class="hs-special">)</span><span>
</span><span id="line-21"></span><span>
</span><span id="line-22"></span><span class="hs-comment">{-
The liberate-case transformation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This module walks over @Core@, and looks for @case@ on free variables.
The criterion is:
        if there is case on a free on the route to the recursive call,
        then the recursive call is replaced with an unfolding.

Example

   f = \ t -&gt; case v of
                 V a b -&gt; a : f t

=&gt; the inner f is replaced.

   f = \ t -&gt; case v of
                 V a b -&gt; a : (letrec
                                f =  \ t -&gt; case v of
                                               V a b -&gt; a : f t
                               in f) t
(note the NEED for shadowing)

=&gt; Simplify

  f = \ t -&gt; case v of
                 V a b -&gt; a : (letrec
                                f = \ t -&gt; a : f t
                               in f t)

Better code, because 'a' is  free inside the inner letrec, rather
than needing projection from v.

Note that this deals with *free variables*.  SpecConstr deals with
*arguments* that are of known form.  E.g.

        last []     = error
        last (x:[]) = x
        last (x:xs) = last xs


Note [Scrutinee with cast]
~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider this:
    f = \ t -&gt; case (v `cast` co) of
                 V a b -&gt; a : f t

Exactly the same optimisation (unrolling one call to f) will work here,
despite the cast.  See mk_alt_env in the Case branch of libCase.


To think about (Apr 94)
~~~~~~~~~~~~~~
Main worry: duplicating code excessively.  At the moment we duplicate
the entire binding group once at each recursive call.  But there may
be a group of recursive calls which share a common set of evaluated
free variables, in which case the duplication is a plain waste.

Another thing we could consider adding is some unfold-threshold thing,
so that we'll only duplicate if the size of the group rhss isn't too
big.

Data types
~~~~~~~~~~
The ``level'' of a binder tells how many
recursive defns lexically enclose the binding
A recursive defn &quot;encloses&quot; its RHS, not its
scope.  For example:
\begin{verbatim}
        letrec f = let g = ... in ...
        in
        let h = ...
        in ...
\end{verbatim}
Here, the level of @f@ is zero, the level of @g@ is one,
and the level of @h@ is zero (NB not one).


************************************************************************
*                                                                      *
         Top-level code
*                                                                      *
************************************************************************
-}</span><span>
</span><span id="line-105"></span><span>
</span><span id="line-106"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#liberateCase"><span class="hs-identifier hs-type">liberateCase</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.Driver.Session.html#DynFlags"><span class="hs-identifier hs-type">DynFlags</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="GHC.Core.html#CoreProgram"><span class="hs-identifier hs-type">CoreProgram</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="GHC.Core.html#CoreProgram"><span class="hs-identifier hs-type">CoreProgram</span></a></span><span>
</span><span id="line-107"></span><span id="liberateCase"><span class="annot"><span class="annottext">liberateCase :: DynFlags -&gt; CoreProgram -&gt; CoreProgram
</span><a href="GHC.Core.Opt.LiberateCase.html#liberateCase"><span class="hs-identifier hs-var hs-var">liberateCase</span></a></span></span><span> </span><span id="local-6989586621680963887"><span class="annot"><span class="annottext">DynFlags
</span><a href="#local-6989586621680963887"><span class="hs-identifier hs-var">dflags</span></a></span></span><span> </span><span id="local-6989586621680963886"><span class="annot"><span class="annottext">CoreProgram
</span><a href="#local-6989586621680963886"><span class="hs-identifier hs-var">binds</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; CoreProgram -&gt; CoreProgram
</span><a href="#local-6989586621680963885"><span class="hs-identifier hs-var">do_prog</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">DynFlags -&gt; LibCaseEnv
</span><a href="GHC.Core.Opt.LiberateCase.html#initEnv"><span class="hs-identifier hs-var">initEnv</span></a></span><span> </span><span class="annot"><span class="annottext">DynFlags
</span><a href="#local-6989586621680963887"><span class="hs-identifier hs-var">dflags</span></a></span><span class="hs-special">)</span><span> </span><span class="annot"><span class="annottext">CoreProgram
</span><a href="#local-6989586621680963886"><span class="hs-identifier hs-var">binds</span></a></span><span>
</span><span id="line-108"></span><span>  </span><span class="hs-keyword">where</span><span>
</span><span id="line-109"></span><span>    </span><span id="local-6989586621680963885"><span class="annot"><span class="annottext">do_prog :: LibCaseEnv -&gt; CoreProgram -&gt; CoreProgram
</span><a href="#local-6989586621680963885"><span class="hs-identifier hs-var hs-var">do_prog</span></a></span></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><span class="hs-identifier">_</span></span><span>   </span><span class="hs-special">[</span><span class="hs-special">]</span><span> </span><span class="hs-glyph">=</span><span> </span><span class="hs-special">[</span><span class="hs-special">]</span><span>
</span><span id="line-110"></span><span>    </span><span class="annot"><a href="#local-6989586621680963885"><span class="hs-identifier hs-var">do_prog</span></a></span><span> </span><span id="local-6989586621680963883"><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963883"><span class="hs-identifier hs-var">env</span></a></span></span><span> </span><span class="hs-special">(</span><span id="local-6989586621680963882"><span class="annot"><span class="annottext">CoreBind
</span><a href="#local-6989586621680963882"><span class="hs-identifier hs-var">bind</span></a></span></span><span class="annot"><span class="hs-glyph hs-type">:</span></span><span id="local-6989586621680963881"><span class="annot"><span class="annottext">CoreProgram
</span><a href="#local-6989586621680963881"><span class="hs-identifier hs-var">binds</span></a></span></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">CoreBind
</span><a href="#local-6989586621680963880"><span class="hs-identifier hs-var">bind'</span></a></span><span> </span><span class="annot"><span class="annottext">CoreBind -&gt; CoreProgram -&gt; CoreProgram
forall a. a -&gt; [a] -&gt; [a]
</span><span class="hs-glyph hs-var">:</span></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; CoreProgram -&gt; CoreProgram
</span><a href="#local-6989586621680963885"><span class="hs-identifier hs-var">do_prog</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963879"><span class="hs-identifier hs-var">env'</span></a></span><span> </span><span class="annot"><span class="annottext">CoreProgram
</span><a href="#local-6989586621680963881"><span class="hs-identifier hs-var">binds</span></a></span><span>
</span><span id="line-111"></span><span>                             </span><span class="hs-keyword">where</span><span>
</span><span id="line-112"></span><span>                               </span><span class="hs-special">(</span><span id="local-6989586621680963879"><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963879"><span class="hs-identifier hs-var">env'</span></a></span></span><span class="hs-special">,</span><span> </span><span id="local-6989586621680963880"><span class="annot"><span class="annottext">CoreBind
</span><a href="#local-6989586621680963880"><span class="hs-identifier hs-var">bind'</span></a></span></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; CoreBind -&gt; (LibCaseEnv, CoreBind)
</span><a href="GHC.Core.Opt.LiberateCase.html#libCaseBind"><span class="hs-identifier hs-var">libCaseBind</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963883"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="annot"><span class="annottext">CoreBind
</span><a href="#local-6989586621680963882"><span class="hs-identifier hs-var">bind</span></a></span><span>
</span><span id="line-113"></span><span>
</span><span id="line-114"></span><span class="hs-comment">{-
************************************************************************
*                                                                      *
         Main payload
*                                                                      *
************************************************************************

Bindings
~~~~~~~~
-}</span><span>
</span><span id="line-124"></span><span>
</span><span id="line-125"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#libCaseBind"><span class="hs-identifier hs-type">libCaseBind</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="GHC.Core.html#CoreBind"><span class="hs-identifier hs-type">CoreBind</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><a href="GHC.Core.html#CoreBind"><span class="hs-identifier hs-type">CoreBind</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-126"></span><span>
</span><span id="line-127"></span><span id="libCaseBind"><span class="annot"><span class="annottext">libCaseBind :: LibCaseEnv -&gt; CoreBind -&gt; (LibCaseEnv, CoreBind)
</span><a href="GHC.Core.Opt.LiberateCase.html#libCaseBind"><span class="hs-identifier hs-var hs-var">libCaseBind</span></a></span></span><span> </span><span id="local-6989586621680963877"><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963877"><span class="hs-identifier hs-var">env</span></a></span></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.html#NonRec"><span class="hs-identifier hs-type">NonRec</span></a></span><span> </span><span id="local-6989586621680963875"><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963875"><span class="hs-identifier hs-var">binder</span></a></span></span><span> </span><span id="local-6989586621680963874"><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963874"><span class="hs-identifier hs-var">rhs</span></a></span></span><span class="hs-special">)</span><span>
</span><span id="line-128"></span><span>  </span><span class="hs-glyph">=</span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">LibCaseEnv -&gt; [CoreBndr] -&gt; LibCaseEnv
</span><a href="GHC.Core.Opt.LiberateCase.html#addBinders"><span class="hs-identifier hs-var">addBinders</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963877"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="hs-special">[</span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963875"><span class="hs-identifier hs-var">binder</span></a></span><span class="hs-special">]</span><span class="hs-special">,</span><span> </span><span class="annot"><span class="annottext">CoreBndr -&gt; Expr CoreBndr -&gt; CoreBind
forall b. b -&gt; Expr b -&gt; Bind b
</span><a href="GHC.Core.html#NonRec"><span class="hs-identifier hs-var">NonRec</span></a></span><span> </span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963875"><span class="hs-identifier hs-var">binder</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">LibCaseEnv -&gt; Expr CoreBndr -&gt; Expr CoreBndr
</span><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963877"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963874"><span class="hs-identifier hs-var">rhs</span></a></span><span class="hs-special">)</span><span class="hs-special">)</span><span>
</span><span id="line-129"></span><span>
</span><span id="line-130"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#libCaseBind"><span class="hs-identifier hs-var">libCaseBind</span></a></span><span> </span><span id="local-6989586621680963871"><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963871"><span class="hs-identifier hs-var">env</span></a></span></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.html#Rec"><span class="hs-identifier hs-type">Rec</span></a></span><span> </span><span id="local-6989586621680963869"><span class="annot"><span class="annottext">[(CoreBndr, Expr CoreBndr)]
</span><a href="#local-6989586621680963869"><span class="hs-identifier hs-var">pairs</span></a></span></span><span class="hs-special">)</span><span>
</span><span id="line-131"></span><span>  </span><span class="hs-glyph">=</span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963868"><span class="hs-identifier hs-var">env_body</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><span class="annottext">[(CoreBndr, Expr CoreBndr)] -&gt; CoreBind
forall b. [(b, Expr b)] -&gt; Bind b
</span><a href="GHC.Core.html#Rec"><span class="hs-identifier hs-var">Rec</span></a></span><span> </span><span class="annot"><span class="annottext">[(CoreBndr, Expr CoreBndr)]
</span><a href="#local-6989586621680963867"><span class="hs-identifier hs-var">pairs'</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-132"></span><span>  </span><span class="hs-keyword">where</span><span>
</span><span id="line-133"></span><span>    </span><span id="local-6989586621680963866"><span class="annot"><span class="annottext">binders :: [CoreBndr]
</span><a href="#local-6989586621680963866"><span class="hs-identifier hs-var hs-var">binders</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">((CoreBndr, Expr CoreBndr) -&gt; CoreBndr)
-&gt; [(CoreBndr, Expr CoreBndr)] -&gt; [CoreBndr]
forall a b. (a -&gt; b) -&gt; [a] -&gt; [b]
</span><a href="../../base/src/GHC.Base.html#map"><span class="hs-identifier hs-var">map</span></a></span><span> </span><span class="annot"><span class="annottext">(CoreBndr, Expr CoreBndr) -&gt; CoreBndr
forall a b. (a, b) -&gt; a
</span><a href="../../base/src/Data.Tuple.html#fst"><span class="hs-identifier hs-var">fst</span></a></span><span> </span><span class="annot"><span class="annottext">[(CoreBndr, Expr CoreBndr)]
</span><a href="#local-6989586621680963869"><span class="hs-identifier hs-var">pairs</span></a></span><span>
</span><span id="line-134"></span><span>
</span><span id="line-135"></span><span>    </span><span id="local-6989586621680963868"><span class="annot"><span class="annottext">env_body :: LibCaseEnv
</span><a href="#local-6989586621680963868"><span class="hs-identifier hs-var hs-var">env_body</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; [CoreBndr] -&gt; LibCaseEnv
</span><a href="GHC.Core.Opt.LiberateCase.html#addBinders"><span class="hs-identifier hs-var">addBinders</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963871"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="annot"><span class="annottext">[CoreBndr]
</span><a href="#local-6989586621680963866"><span class="hs-identifier hs-var">binders</span></a></span><span>
</span><span id="line-136"></span><span>
</span><span id="line-137"></span><span>    </span><span id="local-6989586621680963867"><span class="annot"><span class="annottext">pairs' :: [(CoreBndr, Expr CoreBndr)]
</span><a href="#local-6989586621680963867"><span class="hs-identifier hs-var hs-var">pairs'</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="hs-special">[</span><span class="hs-special">(</span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963865"><span class="hs-identifier hs-var">binder</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; Expr CoreBndr -&gt; Expr CoreBndr
</span><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963864"><span class="hs-identifier hs-var">env_rhs</span></a></span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963863"><span class="hs-identifier hs-var">rhs</span></a></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">|</span><span> </span><span class="hs-special">(</span><span id="local-6989586621680963865"><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963865"><span class="hs-identifier hs-var">binder</span></a></span></span><span class="hs-special">,</span><span id="local-6989586621680963863"><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963863"><span class="hs-identifier hs-var">rhs</span></a></span></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">&lt;-</span><span> </span><span class="annot"><span class="annottext">[(CoreBndr, Expr CoreBndr)]
</span><a href="#local-6989586621680963869"><span class="hs-identifier hs-var">pairs</span></a></span><span class="hs-special">]</span><span>
</span><span id="line-138"></span><span>
</span><span id="line-139"></span><span>        </span><span class="hs-comment">-- We extend the rec-env by binding each Id to its rhs, first</span><span>
</span><span id="line-140"></span><span>        </span><span class="hs-comment">-- processing the rhs with an *un-extended* environment, so</span><span>
</span><span id="line-141"></span><span>        </span><span class="hs-comment">-- that the same process doesn't occur for ever!</span><span>
</span><span id="line-142"></span><span>    </span><span id="local-6989586621680963864"><span class="annot"><span class="annottext">env_rhs :: LibCaseEnv
</span><a href="#local-6989586621680963864"><span class="hs-identifier hs-var hs-var">env_rhs</span></a></span></span><span> </span><span class="hs-glyph">|</span><span> </span><span class="annot"><span class="annottext">Bool
</span><a href="#local-6989586621680963862"><span class="hs-identifier hs-var">is_dupable_bind</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; [(CoreBndr, Expr CoreBndr)] -&gt; LibCaseEnv
</span><a href="GHC.Core.Opt.LiberateCase.html#addRecBinds"><span class="hs-identifier hs-var">addRecBinds</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963871"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="annot"><span class="annottext">[(CoreBndr, Expr CoreBndr)]
</span><a href="#local-6989586621680963860"><span class="hs-identifier hs-var">dup_pairs</span></a></span><span>
</span><span id="line-143"></span><span>            </span><span class="hs-glyph">|</span><span> </span><span class="annot"><span class="annottext">Bool
</span><a href="../../base/src/GHC.Base.html#otherwise"><span class="hs-identifier hs-var">otherwise</span></a></span><span>       </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963871"><span class="hs-identifier hs-var">env</span></a></span><span>
</span><span id="line-144"></span><span>
</span><span id="line-145"></span><span>    </span><span id="local-6989586621680963860"><span class="annot"><span class="annottext">dup_pairs :: [(CoreBndr, Expr CoreBndr)]
</span><a href="#local-6989586621680963860"><span class="hs-identifier hs-var hs-var">dup_pairs</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="hs-special">[</span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">CoreBndr -&gt; CoreBndr
</span><a href="GHC.Types.Id.html#localiseId"><span class="hs-identifier hs-var">localiseId</span></a></span><span> </span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963858"><span class="hs-identifier hs-var">binder</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; Expr CoreBndr -&gt; Expr CoreBndr
</span><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963868"><span class="hs-identifier hs-var">env_body</span></a></span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963857"><span class="hs-identifier hs-var">rhs</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-146"></span><span>                </span><span class="hs-glyph">|</span><span> </span><span class="hs-special">(</span><span id="local-6989586621680963858"><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963858"><span class="hs-identifier hs-var">binder</span></a></span></span><span class="hs-special">,</span><span> </span><span id="local-6989586621680963857"><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963857"><span class="hs-identifier hs-var">rhs</span></a></span></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">&lt;-</span><span> </span><span class="annot"><span class="annottext">[(CoreBndr, Expr CoreBndr)]
</span><a href="#local-6989586621680963869"><span class="hs-identifier hs-var">pairs</span></a></span><span> </span><span class="hs-special">]</span><span>
</span><span id="line-147"></span><span>        </span><span class="hs-comment">-- localiseID : see Note [Need to localiseId in libCaseBind]</span><span>
</span><span id="line-148"></span><span>
</span><span id="line-149"></span><span>    </span><span id="local-6989586621680963862"><span class="annot"><span class="annottext">is_dupable_bind :: Bool
</span><a href="#local-6989586621680963862"><span class="hs-identifier hs-var hs-var">is_dupable_bind</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">Bool
</span><a href="#local-6989586621680963854"><span class="hs-identifier hs-var">small_enough</span></a></span><span> </span><span class="annot"><span class="annottext">Bool -&gt; Bool -&gt; Bool
</span><span class="hs-operator hs-var">&amp;&amp;</span></span><span> </span><span class="annot"><span class="annottext">((CoreBndr, Expr CoreBndr) -&gt; Bool)
-&gt; [(CoreBndr, Expr CoreBndr)] -&gt; Bool
forall (t :: * -&gt; *) a. Foldable t =&gt; (a -&gt; Bool) -&gt; t a -&gt; Bool
</span><a href="../../base/src/Data.Foldable.html#all"><span class="hs-identifier hs-var">all</span></a></span><span> </span><span class="annot"><span class="annottext">(CoreBndr, Expr CoreBndr) -&gt; Bool
forall {b}. (CoreBndr, b) -&gt; Bool
</span><a href="#local-6989586621680963851"><span class="hs-identifier hs-var">ok_pair</span></a></span><span> </span><span class="annot"><span class="annottext">[(CoreBndr, Expr CoreBndr)]
</span><a href="#local-6989586621680963869"><span class="hs-identifier hs-var">pairs</span></a></span><span>
</span><span id="line-150"></span><span>
</span><span id="line-151"></span><span>    </span><span class="hs-comment">-- Size: we are going to duplicate dup_pairs; to find their</span><span>
</span><span id="line-152"></span><span>    </span><span class="hs-comment">--       size, build a fake binding (let { dup_pairs } in (),</span><span>
</span><span id="line-153"></span><span>    </span><span class="hs-comment">--       and find the size of that</span><span>
</span><span id="line-154"></span><span>    </span><span class="hs-comment">-- See Note [Small enough]</span><span>
</span><span id="line-155"></span><span>    </span><span id="local-6989586621680963854"><span class="annot"><span class="annottext">small_enough :: Bool
</span><a href="#local-6989586621680963854"><span class="hs-identifier hs-var hs-var">small_enough</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="hs-keyword">case</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; Maybe LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#bombOutSize"><span class="hs-identifier hs-var">bombOutSize</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963871"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="hs-keyword">of</span><span>
</span><span id="line-156"></span><span>                      </span><span class="annot"><span class="annottext">Maybe LibCaseLevel
</span><a href="../../base/src/GHC.Maybe.html#Nothing"><span class="hs-identifier hs-var">Nothing</span></a></span><span>   </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><span class="annottext">Bool
</span><span class="hs-identifier hs-var">True</span></span><span>   </span><span class="hs-comment">-- Infinity</span><span>
</span><span id="line-157"></span><span>                      </span><span class="annot"><a href="../../base/src/GHC.Maybe.html#Just"><span class="hs-identifier hs-type">Just</span></a></span><span> </span><span id="local-6989586621680963849"><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963849"><span class="hs-identifier hs-var">size</span></a></span></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><span class="annottext">DynFlags -&gt; LibCaseLevel -&gt; Expr CoreBndr -&gt; Bool
</span><a href="GHC.Core.Unfold.html#couldBeSmallEnoughToInline"><span class="hs-identifier hs-var">couldBeSmallEnoughToInline</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">LibCaseEnv -&gt; DynFlags
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_dflags"><span class="hs-identifier hs-var hs-var">lc_dflags</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963871"><span class="hs-identifier hs-var">env</span></a></span><span class="hs-special">)</span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963849"><span class="hs-identifier hs-var">size</span></a></span><span> </span><span class="annot"><span class="annottext">(Expr CoreBndr -&gt; Bool) -&gt; Expr CoreBndr -&gt; Bool
forall a b. (a -&gt; b) -&gt; a -&gt; b
</span><a href="../../base/src/GHC.Base.html#%24"><span class="hs-operator hs-var">$</span></a></span><span>
</span><span id="line-158"></span><span>                                   </span><span class="annot"><span class="annottext">CoreBind -&gt; Expr CoreBndr -&gt; Expr CoreBndr
forall b. Bind b -&gt; Expr b -&gt; Expr b
</span><a href="GHC.Core.html#Let"><span class="hs-identifier hs-var">Let</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">[(CoreBndr, Expr CoreBndr)] -&gt; CoreBind
forall b. [(b, Expr b)] -&gt; Bind b
</span><a href="GHC.Core.html#Rec"><span class="hs-identifier hs-var">Rec</span></a></span><span> </span><span class="annot"><span class="annottext">[(CoreBndr, Expr CoreBndr)]
</span><a href="#local-6989586621680963860"><span class="hs-identifier hs-var">dup_pairs</span></a></span><span class="hs-special">)</span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">CoreBndr -&gt; Expr CoreBndr
forall b. CoreBndr -&gt; Expr b
</span><a href="GHC.Core.html#Var"><span class="hs-identifier hs-var">Var</span></a></span><span> </span><span class="annot"><span class="annottext">CoreBndr
</span><a href="GHC.Builtin.Types.html#unitDataConId"><span class="hs-identifier hs-var">unitDataConId</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-159"></span><span>
</span><span id="line-160"></span><span>    </span><span id="local-6989586621680963851"><span class="annot"><span class="annottext">ok_pair :: (CoreBndr, b) -&gt; Bool
</span><a href="#local-6989586621680963851"><span class="hs-identifier hs-var hs-var">ok_pair</span></a></span></span><span> </span><span class="hs-special">(</span><span id="local-6989586621680963842"><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963842"><span class="hs-identifier hs-var">id</span></a></span></span><span class="hs-special">,</span><span class="annot"><span class="annottext">b
</span><span class="hs-identifier">_</span></span><span class="hs-special">)</span><span>
</span><span id="line-161"></span><span>        </span><span class="hs-glyph">=</span><span>  </span><span class="annot"><span class="annottext">CoreBndr -&gt; LibCaseLevel
</span><a href="GHC.Types.Id.html#idArity"><span class="hs-identifier hs-var">idArity</span></a></span><span> </span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963842"><span class="hs-identifier hs-var">id</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseLevel -&gt; LibCaseLevel -&gt; Bool
forall a. Ord a =&gt; a -&gt; a -&gt; Bool
</span><span class="hs-operator hs-var">&gt;</span></span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><span class="hs-number">0</span></span><span>       </span><span class="hs-comment">-- Note [Only functions!]</span><span>
</span><span id="line-162"></span><span>        </span><span class="annot"><span class="annottext">Bool -&gt; Bool -&gt; Bool
</span><span class="hs-operator hs-var">&amp;&amp;</span></span><span> </span><span class="annot"><span class="annottext">Bool -&gt; Bool
</span><span class="hs-identifier hs-var">not</span></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">CoreBndr -&gt; Bool
</span><a href="GHC.Types.Id.html#isDeadEndId"><span class="hs-identifier hs-var">isDeadEndId</span></a></span><span> </span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963842"><span class="hs-identifier hs-var">id</span></a></span><span class="hs-special">)</span><span> </span><span class="hs-comment">-- Note [Not bottoming ids]</span><span>
</span><span id="line-163"></span><span>
</span><span id="line-164"></span><span class="hs-comment">{- Note [Not bottoming Ids]
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Do not specialise error-functions (this is unusual, but I once saw it,
(actually in Data.Typable.Internal)

Note [Only functions!]
~~~~~~~~~~~~~~~~~~~~~~
Consider the following code

       f = g (case v of V a b -&gt; a : t f)

where g is expensive. If we aren't careful, liberate case will turn this into

       f = g (case v of
               V a b -&gt; a : t (letrec f = g (case v of V a b -&gt; a : f t)
                                in f)
             )

Yikes! We evaluate g twice. This leads to a O(2^n) explosion
if g calls back to the same code recursively.

Solution: make sure that we only do the liberate-case thing on *functions*

Note [Small enough]
~~~~~~~~~~~~~~~~~~~
Consider
  \fv. letrec
         f = \x. BIG...(case fv of { (a,b) -&gt; ...g.. })...
         g = \y. SMALL...f...

Then we *can* in principle do liberate-case on 'g' (small RHS) but not
for 'f' (too big).  But doing so is not profitable, because duplicating
'g' at its call site in 'f' doesn't get rid of any cases.  So we just
ask for the whole group to be small enough.

Note [Need to localiseId in libCaseBind]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The call to localiseId is needed for two subtle reasons
(a)  Reset the export flags on the binders so
        that we don't get name clashes on exported things if the
        local binding floats out to top level.  This is most unlikely
        to happen, since the whole point concerns free variables.
        But resetting the export flag is right regardless.

(b)  Make the name an Internal one.  External Names should never be
        nested; if it were floated to the top level, we'd get a name
        clash at code generation time.

Expressions
~~~~~~~~~~~
-}</span><span>
</span><span id="line-215"></span><span>
</span><span id="line-216"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-type">libCase</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span>
</span><span id="line-217"></span><span>        </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="GHC.Core.html#CoreExpr"><span class="hs-identifier hs-type">CoreExpr</span></a></span><span>
</span><span id="line-218"></span><span>        </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="GHC.Core.html#CoreExpr"><span class="hs-identifier hs-type">CoreExpr</span></a></span><span>
</span><span id="line-219"></span><span>
</span><span id="line-220"></span><span id="libCase"><span class="annot"><span class="annottext">libCase :: LibCaseEnv -&gt; Expr CoreBndr -&gt; Expr CoreBndr
</span><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var hs-var">libCase</span></a></span></span><span> </span><span id="local-6989586621680963836"><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963836"><span class="hs-identifier hs-var">env</span></a></span></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.html#Var"><span class="hs-identifier hs-type">Var</span></a></span><span> </span><span id="local-6989586621680963835"><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963835"><span class="hs-identifier hs-var">v</span></a></span></span><span class="hs-special">)</span><span>             </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; CoreBndr -&gt; [Expr CoreBndr] -&gt; Expr CoreBndr
</span><a href="GHC.Core.Opt.LiberateCase.html#libCaseApp"><span class="hs-identifier hs-var">libCaseApp</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963836"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963835"><span class="hs-identifier hs-var">v</span></a></span><span> </span><span class="hs-special">[</span><span class="hs-special">]</span><span>
</span><span id="line-221"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><span class="hs-identifier">_</span></span><span>   </span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.html#Lit"><span class="hs-identifier hs-type">Lit</span></a></span><span> </span><span id="local-6989586621680963832"><span class="annot"><span class="annottext">Literal
</span><a href="#local-6989586621680963832"><span class="hs-identifier hs-var">lit</span></a></span></span><span class="hs-special">)</span><span>           </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">Literal -&gt; Expr CoreBndr
forall b. Literal -&gt; Expr b
</span><a href="GHC.Core.html#Lit"><span class="hs-identifier hs-var">Lit</span></a></span><span> </span><span class="annot"><span class="annottext">Literal
</span><a href="#local-6989586621680963832"><span class="hs-identifier hs-var">lit</span></a></span><span>
</span><span id="line-222"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><span class="hs-identifier">_</span></span><span>   </span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.html#Type"><span class="hs-identifier hs-type">Type</span></a></span><span> </span><span id="local-6989586621680963830"><span class="annot"><span class="annottext">Type
</span><a href="#local-6989586621680963830"><span class="hs-identifier hs-var">ty</span></a></span></span><span class="hs-special">)</span><span>           </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">Type -&gt; Expr CoreBndr
forall b. Type -&gt; Expr b
</span><a href="GHC.Core.html#Type"><span class="hs-identifier hs-var">Type</span></a></span><span> </span><span class="annot"><span class="annottext">Type
</span><a href="#local-6989586621680963830"><span class="hs-identifier hs-var">ty</span></a></span><span>
</span><span id="line-223"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><span class="hs-identifier">_</span></span><span>   </span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.html#Coercion"><span class="hs-identifier hs-type">Coercion</span></a></span><span> </span><span id="local-6989586621680963828"><span class="annot"><span class="annottext">Coercion
</span><a href="#local-6989586621680963828"><span class="hs-identifier hs-var">co</span></a></span></span><span class="hs-special">)</span><span>       </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">Coercion -&gt; Expr CoreBndr
forall b. Coercion -&gt; Expr b
</span><a href="GHC.Core.html#Coercion"><span class="hs-identifier hs-var">Coercion</span></a></span><span> </span><span class="annot"><span class="annottext">Coercion
</span><a href="#local-6989586621680963828"><span class="hs-identifier hs-var">co</span></a></span><span>
</span><span id="line-224"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span id="local-6989586621680963827"><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963827"><span class="hs-identifier hs-var">env</span></a></span></span><span> </span><span id="local-6989586621680963826"><span class="annot"><span class="annottext">e :: Expr CoreBndr
</span><a href="#local-6989586621680963826"><span class="hs-identifier hs-var">e</span></a></span></span><span class="hs-glyph">@</span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.html#App"><span class="hs-identifier hs-type">App</span></a></span><span> </span><span class="hs-special">{</span><span class="hs-special">}</span><span class="hs-special">)</span><span>          </span><span class="hs-glyph">|</span><span> </span><span class="hs-keyword">let</span><span> </span><span class="hs-special">(</span><span id="local-6989586621680963824"><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963824"><span class="hs-identifier hs-var">fun</span></a></span></span><span class="hs-special">,</span><span> </span><span id="local-6989586621680963823"><span class="annot"><span class="annottext">[Expr CoreBndr]
</span><a href="#local-6989586621680963823"><span class="hs-identifier hs-var">args</span></a></span></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr -&gt; (Expr CoreBndr, [Expr CoreBndr])
forall b. Expr b -&gt; (Expr b, [Expr b])
</span><a href="GHC.Core.html#collectArgs"><span class="hs-identifier hs-var">collectArgs</span></a></span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963826"><span class="hs-identifier hs-var">e</span></a></span><span>
</span><span id="line-225"></span><span>                                </span><span class="hs-special">,</span><span> </span><span class="annot"><a href="GHC.Core.html#Var"><span class="hs-identifier hs-type">Var</span></a></span><span> </span><span id="local-6989586621680963821"><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963821"><span class="hs-identifier hs-var">v</span></a></span></span><span> </span><span class="hs-glyph">&lt;-</span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963824"><span class="hs-identifier hs-var">fun</span></a></span><span>
</span><span id="line-226"></span><span>                                </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; CoreBndr -&gt; [Expr CoreBndr] -&gt; Expr CoreBndr
</span><a href="GHC.Core.Opt.LiberateCase.html#libCaseApp"><span class="hs-identifier hs-var">libCaseApp</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963827"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963821"><span class="hs-identifier hs-var">v</span></a></span><span> </span><span class="annot"><span class="annottext">[Expr CoreBndr]
</span><a href="#local-6989586621680963823"><span class="hs-identifier hs-var">args</span></a></span><span>
</span><span id="line-227"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span id="local-6989586621680963820"><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963820"><span class="hs-identifier hs-var">env</span></a></span></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.html#App"><span class="hs-identifier hs-type">App</span></a></span><span> </span><span id="local-6989586621680963819"><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963819"><span class="hs-identifier hs-var">fun</span></a></span></span><span> </span><span id="local-6989586621680963818"><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963818"><span class="hs-identifier hs-var">arg</span></a></span></span><span class="hs-special">)</span><span>       </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr -&gt; Expr CoreBndr -&gt; Expr CoreBndr
forall b. Expr b -&gt; Expr b -&gt; Expr b
</span><a href="GHC.Core.html#App"><span class="hs-identifier hs-var">App</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">LibCaseEnv -&gt; Expr CoreBndr -&gt; Expr CoreBndr
</span><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963820"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963819"><span class="hs-identifier hs-var">fun</span></a></span><span class="hs-special">)</span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">LibCaseEnv -&gt; Expr CoreBndr -&gt; Expr CoreBndr
</span><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963820"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963818"><span class="hs-identifier hs-var">arg</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-228"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span id="local-6989586621680963817"><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963817"><span class="hs-identifier hs-var">env</span></a></span></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.html#Tick"><span class="hs-identifier hs-type">Tick</span></a></span><span> </span><span id="local-6989586621680963815"><span class="annot"><span class="annottext">Tickish CoreBndr
</span><a href="#local-6989586621680963815"><span class="hs-identifier hs-var">tickish</span></a></span></span><span> </span><span id="local-6989586621680963814"><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963814"><span class="hs-identifier hs-var">body</span></a></span></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">Tickish CoreBndr -&gt; Expr CoreBndr -&gt; Expr CoreBndr
forall b. Tickish CoreBndr -&gt; Expr b -&gt; Expr b
</span><a href="GHC.Core.html#Tick"><span class="hs-identifier hs-var">Tick</span></a></span><span> </span><span class="annot"><span class="annottext">Tickish CoreBndr
</span><a href="#local-6989586621680963815"><span class="hs-identifier hs-var">tickish</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">LibCaseEnv -&gt; Expr CoreBndr -&gt; Expr CoreBndr
</span><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963817"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963814"><span class="hs-identifier hs-var">body</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-229"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span id="local-6989586621680963813"><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963813"><span class="hs-identifier hs-var">env</span></a></span></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.html#Cast"><span class="hs-identifier hs-type">Cast</span></a></span><span> </span><span id="local-6989586621680963811"><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963811"><span class="hs-identifier hs-var">e</span></a></span></span><span> </span><span id="local-6989586621680963810"><span class="annot"><span class="annottext">Coercion
</span><a href="#local-6989586621680963810"><span class="hs-identifier hs-var">co</span></a></span></span><span class="hs-special">)</span><span>         </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr -&gt; Coercion -&gt; Expr CoreBndr
forall b. Expr b -&gt; Coercion -&gt; Expr b
</span><a href="GHC.Core.html#Cast"><span class="hs-identifier hs-var">Cast</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">LibCaseEnv -&gt; Expr CoreBndr -&gt; Expr CoreBndr
</span><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963813"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963811"><span class="hs-identifier hs-var">e</span></a></span><span class="hs-special">)</span><span> </span><span class="annot"><span class="annottext">Coercion
</span><a href="#local-6989586621680963810"><span class="hs-identifier hs-var">co</span></a></span><span>
</span><span id="line-230"></span><span>
</span><span id="line-231"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span id="local-6989586621680963809"><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963809"><span class="hs-identifier hs-var">env</span></a></span></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.html#Lam"><span class="hs-identifier hs-type">Lam</span></a></span><span> </span><span id="local-6989586621680963807"><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963807"><span class="hs-identifier hs-var">binder</span></a></span></span><span> </span><span id="local-6989586621680963806"><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963806"><span class="hs-identifier hs-var">body</span></a></span></span><span class="hs-special">)</span><span>
</span><span id="line-232"></span><span>  </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">CoreBndr -&gt; Expr CoreBndr -&gt; Expr CoreBndr
forall b. b -&gt; Expr b -&gt; Expr b
</span><a href="GHC.Core.html#Lam"><span class="hs-identifier hs-var">Lam</span></a></span><span> </span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963807"><span class="hs-identifier hs-var">binder</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">LibCaseEnv -&gt; Expr CoreBndr -&gt; Expr CoreBndr
</span><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">LibCaseEnv -&gt; [CoreBndr] -&gt; LibCaseEnv
</span><a href="GHC.Core.Opt.LiberateCase.html#addBinders"><span class="hs-identifier hs-var">addBinders</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963809"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="hs-special">[</span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963807"><span class="hs-identifier hs-var">binder</span></a></span><span class="hs-special">]</span><span class="hs-special">)</span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963806"><span class="hs-identifier hs-var">body</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-233"></span><span>
</span><span id="line-234"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span id="local-6989586621680963805"><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963805"><span class="hs-identifier hs-var">env</span></a></span></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.html#Let"><span class="hs-identifier hs-type">Let</span></a></span><span> </span><span id="local-6989586621680963804"><span class="annot"><span class="annottext">CoreBind
</span><a href="#local-6989586621680963804"><span class="hs-identifier hs-var">bind</span></a></span></span><span> </span><span id="local-6989586621680963803"><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963803"><span class="hs-identifier hs-var">body</span></a></span></span><span class="hs-special">)</span><span>
</span><span id="line-235"></span><span>  </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">CoreBind -&gt; Expr CoreBndr -&gt; Expr CoreBndr
forall b. Bind b -&gt; Expr b -&gt; Expr b
</span><a href="GHC.Core.html#Let"><span class="hs-identifier hs-var">Let</span></a></span><span> </span><span class="annot"><span class="annottext">CoreBind
</span><a href="#local-6989586621680963802"><span class="hs-identifier hs-var">bind'</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">LibCaseEnv -&gt; Expr CoreBndr -&gt; Expr CoreBndr
</span><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963801"><span class="hs-identifier hs-var">env_body</span></a></span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963803"><span class="hs-identifier hs-var">body</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-236"></span><span>  </span><span class="hs-keyword">where</span><span>
</span><span id="line-237"></span><span>    </span><span class="hs-special">(</span><span id="local-6989586621680963801"><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963801"><span class="hs-identifier hs-var">env_body</span></a></span></span><span class="hs-special">,</span><span> </span><span id="local-6989586621680963802"><span class="annot"><span class="annottext">CoreBind
</span><a href="#local-6989586621680963802"><span class="hs-identifier hs-var">bind'</span></a></span></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; CoreBind -&gt; (LibCaseEnv, CoreBind)
</span><a href="GHC.Core.Opt.LiberateCase.html#libCaseBind"><span class="hs-identifier hs-var">libCaseBind</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963805"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="annot"><span class="annottext">CoreBind
</span><a href="#local-6989586621680963804"><span class="hs-identifier hs-var">bind</span></a></span><span>
</span><span id="line-238"></span><span>
</span><span id="line-239"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span id="local-6989586621680963800"><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963800"><span class="hs-identifier hs-var">env</span></a></span></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.html#Case"><span class="hs-identifier hs-type">Case</span></a></span><span> </span><span id="local-6989586621680963798"><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963798"><span class="hs-identifier hs-var">scrut</span></a></span></span><span> </span><span id="local-6989586621680963797"><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963797"><span class="hs-identifier hs-var">bndr</span></a></span></span><span> </span><span id="local-6989586621680963796"><span class="annot"><span class="annottext">Type
</span><a href="#local-6989586621680963796"><span class="hs-identifier hs-var">ty</span></a></span></span><span> </span><span id="local-6989586621680963795"><span class="annot"><span class="annottext">[Alt CoreBndr]
</span><a href="#local-6989586621680963795"><span class="hs-identifier hs-var">alts</span></a></span></span><span class="hs-special">)</span><span>
</span><span id="line-240"></span><span>  </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr
-&gt; CoreBndr -&gt; Type -&gt; [Alt CoreBndr] -&gt; Expr CoreBndr
forall b. Expr b -&gt; b -&gt; Type -&gt; [Alt b] -&gt; Expr b
</span><a href="GHC.Core.html#Case"><span class="hs-identifier hs-var">Case</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">LibCaseEnv -&gt; Expr CoreBndr -&gt; Expr CoreBndr
</span><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963800"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963798"><span class="hs-identifier hs-var">scrut</span></a></span><span class="hs-special">)</span><span> </span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963797"><span class="hs-identifier hs-var">bndr</span></a></span><span> </span><span class="annot"><span class="annottext">Type
</span><a href="#local-6989586621680963796"><span class="hs-identifier hs-var">ty</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">(Alt CoreBndr -&gt; Alt CoreBndr) -&gt; [Alt CoreBndr] -&gt; [Alt CoreBndr]
forall a b. (a -&gt; b) -&gt; [a] -&gt; [b]
</span><a href="../../base/src/GHC.Base.html#map"><span class="hs-identifier hs-var">map</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">LibCaseEnv -&gt; Alt CoreBndr -&gt; Alt CoreBndr
</span><a href="GHC.Core.Opt.LiberateCase.html#libCaseAlt"><span class="hs-identifier hs-var">libCaseAlt</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963793"><span class="hs-identifier hs-var">env_alts</span></a></span><span class="hs-special">)</span><span> </span><span class="annot"><span class="annottext">[Alt CoreBndr]
</span><a href="#local-6989586621680963795"><span class="hs-identifier hs-var">alts</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-241"></span><span>  </span><span class="hs-keyword">where</span><span>
</span><span id="line-242"></span><span>    </span><span id="local-6989586621680963793"><span class="annot"><span class="annottext">env_alts :: LibCaseEnv
</span><a href="#local-6989586621680963793"><span class="hs-identifier hs-var hs-var">env_alts</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; [CoreBndr] -&gt; LibCaseEnv
</span><a href="GHC.Core.Opt.LiberateCase.html#addBinders"><span class="hs-identifier hs-var">addBinders</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">Expr CoreBndr -&gt; LibCaseEnv
forall {b}. Expr b -&gt; LibCaseEnv
</span><a href="#local-6989586621680963792"><span class="hs-identifier hs-var">mk_alt_env</span></a></span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963798"><span class="hs-identifier hs-var">scrut</span></a></span><span class="hs-special">)</span><span> </span><span class="hs-special">[</span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963797"><span class="hs-identifier hs-var">bndr</span></a></span><span class="hs-special">]</span><span>
</span><span id="line-243"></span><span>    </span><span id="local-6989586621680963792"><span class="annot"><span class="annottext">mk_alt_env :: Expr b -&gt; LibCaseEnv
</span><a href="#local-6989586621680963792"><span class="hs-identifier hs-var hs-var">mk_alt_env</span></a></span></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.html#Var"><span class="hs-identifier hs-type">Var</span></a></span><span> </span><span id="local-6989586621680963791"><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963791"><span class="hs-identifier hs-var">scrut_var</span></a></span></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; CoreBndr -&gt; LibCaseEnv
</span><a href="GHC.Core.Opt.LiberateCase.html#addScrutedVar"><span class="hs-identifier hs-var">addScrutedVar</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963800"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963791"><span class="hs-identifier hs-var">scrut_var</span></a></span><span>
</span><span id="line-244"></span><span>    </span><span class="annot"><a href="#local-6989586621680963792"><span class="hs-identifier hs-var">mk_alt_env</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.html#Cast"><span class="hs-identifier hs-type">Cast</span></a></span><span> </span><span id="local-6989586621680963789"><span class="annot"><span class="annottext">Expr b
</span><a href="#local-6989586621680963789"><span class="hs-identifier hs-var">scrut</span></a></span></span><span> </span><span class="annot"><span class="annottext">Coercion
</span><span class="hs-identifier">_</span></span><span class="hs-special">)</span><span>  </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">Expr b -&gt; LibCaseEnv
</span><a href="#local-6989586621680963792"><span class="hs-identifier hs-var">mk_alt_env</span></a></span><span> </span><span class="annot"><span class="annottext">Expr b
</span><a href="#local-6989586621680963789"><span class="hs-identifier hs-var">scrut</span></a></span><span>       </span><span class="hs-comment">-- Note [Scrutinee with cast]</span><span>
</span><span id="line-245"></span><span>    </span><span class="annot"><a href="#local-6989586621680963792"><span class="hs-identifier hs-var">mk_alt_env</span></a></span><span> </span><span class="annot"><span class="annottext">Expr b
</span><span class="hs-identifier">_</span></span><span>               </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963800"><span class="hs-identifier hs-var">env</span></a></span><span>
</span><span id="line-246"></span><span>
</span><span id="line-247"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#libCaseAlt"><span class="hs-identifier hs-type">libCaseAlt</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.html#AltCon"><span class="hs-identifier hs-type">AltCon</span></a></span><span class="hs-special">,</span><span> </span><span class="hs-special">[</span><span class="annot"><a href="GHC.Core.html#CoreBndr"><span class="hs-identifier hs-type">CoreBndr</span></a></span><span class="hs-special">]</span><span class="hs-special">,</span><span> </span><span class="annot"><a href="GHC.Core.html#CoreExpr"><span class="hs-identifier hs-type">CoreExpr</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-248"></span><span>                         </span><span class="hs-glyph">-&gt;</span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.html#AltCon"><span class="hs-identifier hs-type">AltCon</span></a></span><span class="hs-special">,</span><span> </span><span class="hs-special">[</span><span class="annot"><a href="GHC.Core.html#CoreBndr"><span class="hs-identifier hs-type">CoreBndr</span></a></span><span class="hs-special">]</span><span class="hs-special">,</span><span> </span><span class="annot"><a href="GHC.Core.html#CoreExpr"><span class="hs-identifier hs-type">CoreExpr</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-249"></span><span id="libCaseAlt"><span class="annot"><span class="annottext">libCaseAlt :: LibCaseEnv -&gt; Alt CoreBndr -&gt; Alt CoreBndr
</span><a href="GHC.Core.Opt.LiberateCase.html#libCaseAlt"><span class="hs-identifier hs-var hs-var">libCaseAlt</span></a></span></span><span> </span><span id="local-6989586621680963788"><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963788"><span class="hs-identifier hs-var">env</span></a></span></span><span> </span><span class="hs-special">(</span><span id="local-6989586621680963787"><span class="annot"><span class="annottext">AltCon
</span><a href="#local-6989586621680963787"><span class="hs-identifier hs-var">con</span></a></span></span><span class="hs-special">,</span><span id="local-6989586621680963786"><span class="annot"><span class="annottext">[CoreBndr]
</span><a href="#local-6989586621680963786"><span class="hs-identifier hs-var">args</span></a></span></span><span class="hs-special">,</span><span id="local-6989586621680963785"><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963785"><span class="hs-identifier hs-var">rhs</span></a></span></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">=</span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">AltCon
</span><a href="#local-6989586621680963787"><span class="hs-identifier hs-var">con</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><span class="annottext">[CoreBndr]
</span><a href="#local-6989586621680963786"><span class="hs-identifier hs-var">args</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; Expr CoreBndr -&gt; Expr CoreBndr
</span><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">LibCaseEnv -&gt; [CoreBndr] -&gt; LibCaseEnv
</span><a href="GHC.Core.Opt.LiberateCase.html#addBinders"><span class="hs-identifier hs-var">addBinders</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963788"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="annot"><span class="annottext">[CoreBndr]
</span><a href="#local-6989586621680963786"><span class="hs-identifier hs-var">args</span></a></span><span class="hs-special">)</span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963785"><span class="hs-identifier hs-var">rhs</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-250"></span><span>
</span><span id="line-251"></span><span class="hs-comment">{-
Ids
~~~

To unfold, we can't just wrap the id itself in its binding if it's a join point:

  jump j a b c  =&gt;  (joinrec j x y z = ... in jump j) a b c -- wrong!!!

Every jump must provide all arguments, so we have to be careful to wrap the
whole jump instead:

  jump j a b c  =&gt;  joinrec j x y z = ... in jump j a b c -- right

-}</span><span>
</span><span id="line-265"></span><span>
</span><span id="line-266"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#libCaseApp"><span class="hs-identifier hs-type">libCaseApp</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="GHC.Types.Var.html#Id"><span class="hs-identifier hs-type">Id</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="hs-special">[</span><span class="annot"><a href="GHC.Core.html#CoreExpr"><span class="hs-identifier hs-type">CoreExpr</span></a></span><span class="hs-special">]</span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="GHC.Core.html#CoreExpr"><span class="hs-identifier hs-type">CoreExpr</span></a></span><span>
</span><span id="line-267"></span><span id="libCaseApp"><span class="annot"><span class="annottext">libCaseApp :: LibCaseEnv -&gt; CoreBndr -&gt; [Expr CoreBndr] -&gt; Expr CoreBndr
</span><a href="GHC.Core.Opt.LiberateCase.html#libCaseApp"><span class="hs-identifier hs-var hs-var">libCaseApp</span></a></span></span><span> </span><span id="local-6989586621680963783"><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963783"><span class="hs-identifier hs-var">env</span></a></span></span><span> </span><span id="local-6989586621680963782"><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963782"><span class="hs-identifier hs-var">v</span></a></span></span><span> </span><span id="local-6989586621680963781"><span class="annot"><span class="annottext">[Expr CoreBndr]
</span><a href="#local-6989586621680963781"><span class="hs-identifier hs-var">args</span></a></span></span><span>
</span><span id="line-268"></span><span>  </span><span class="hs-glyph">|</span><span> </span><span class="annot"><a href="../../base/src/GHC.Maybe.html#Just"><span class="hs-identifier hs-type">Just</span></a></span><span> </span><span id="local-6989586621680963780"><span class="annot"><span class="annottext">CoreBind
</span><a href="#local-6989586621680963780"><span class="hs-identifier hs-var">the_bind</span></a></span></span><span> </span><span class="hs-glyph">&lt;-</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; CoreBndr -&gt; Maybe CoreBind
</span><a href="GHC.Core.Opt.LiberateCase.html#lookupRecId"><span class="hs-identifier hs-var">lookupRecId</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963783"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963782"><span class="hs-identifier hs-var">v</span></a></span><span>  </span><span class="hs-comment">-- It's a use of a recursive thing</span><span>
</span><span id="line-269"></span><span>  </span><span class="hs-special">,</span><span> </span><span class="annot"><span class="annottext">[CoreBndr] -&gt; Bool
forall a. [a] -&gt; Bool
</span><a href="GHC.Utils.Misc.html#notNull"><span class="hs-identifier hs-var">notNull</span></a></span><span> </span><span class="annot"><span class="annottext">[CoreBndr]
</span><a href="#local-6989586621680963778"><span class="hs-identifier hs-var">free_scruts</span></a></span><span>                 </span><span class="hs-comment">-- with free vars scrutinised in RHS</span><span>
</span><span id="line-270"></span><span>  </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">CoreBind -&gt; Expr CoreBndr -&gt; Expr CoreBndr
forall b. Bind b -&gt; Expr b -&gt; Expr b
</span><a href="GHC.Core.html#Let"><span class="hs-identifier hs-var">Let</span></a></span><span> </span><span class="annot"><span class="annottext">CoreBind
</span><a href="#local-6989586621680963780"><span class="hs-identifier hs-var">the_bind</span></a></span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963777"><span class="hs-identifier hs-var">expr'</span></a></span><span>
</span><span id="line-271"></span><span>
</span><span id="line-272"></span><span>  </span><span class="hs-glyph">|</span><span> </span><span class="annot"><span class="annottext">Bool
</span><a href="../../base/src/GHC.Base.html#otherwise"><span class="hs-identifier hs-var">otherwise</span></a></span><span>
</span><span id="line-273"></span><span>  </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr
</span><a href="#local-6989586621680963777"><span class="hs-identifier hs-var">expr'</span></a></span><span>
</span><span id="line-274"></span><span>
</span><span id="line-275"></span><span>  </span><span class="hs-keyword">where</span><span>
</span><span id="line-276"></span><span>    </span><span id="local-6989586621680963776"><span class="annot"><span class="annottext">rec_id_level :: LibCaseLevel
</span><a href="#local-6989586621680963776"><span class="hs-identifier hs-var hs-var">rec_id_level</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; CoreBndr -&gt; LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#lookupLevel"><span class="hs-identifier hs-var">lookupLevel</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963783"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963782"><span class="hs-identifier hs-var">v</span></a></span><span>
</span><span id="line-277"></span><span>    </span><span id="local-6989586621680963778"><span class="annot"><span class="annottext">free_scruts :: [CoreBndr]
</span><a href="#local-6989586621680963778"><span class="hs-identifier hs-var hs-var">free_scruts</span></a></span></span><span>  </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; LibCaseLevel -&gt; [CoreBndr]
</span><a href="GHC.Core.Opt.LiberateCase.html#freeScruts"><span class="hs-identifier hs-var">freeScruts</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963783"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963776"><span class="hs-identifier hs-var">rec_id_level</span></a></span><span>
</span><span id="line-278"></span><span>    </span><span id="local-6989586621680963777"><span class="annot"><span class="annottext">expr' :: Expr CoreBndr
</span><a href="#local-6989586621680963777"><span class="hs-identifier hs-var hs-var">expr'</span></a></span></span><span>        </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">Expr CoreBndr -&gt; [Expr CoreBndr] -&gt; Expr CoreBndr
forall b. Expr b -&gt; [Expr b] -&gt; Expr b
</span><a href="GHC.Core.html#mkApps"><span class="hs-identifier hs-var">mkApps</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">CoreBndr -&gt; Expr CoreBndr
forall b. CoreBndr -&gt; Expr b
</span><a href="GHC.Core.html#Var"><span class="hs-identifier hs-var">Var</span></a></span><span> </span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963782"><span class="hs-identifier hs-var">v</span></a></span><span class="hs-special">)</span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">(Expr CoreBndr -&gt; Expr CoreBndr)
-&gt; [Expr CoreBndr] -&gt; [Expr CoreBndr]
forall a b. (a -&gt; b) -&gt; [a] -&gt; [b]
</span><a href="../../base/src/GHC.Base.html#map"><span class="hs-identifier hs-var">map</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">LibCaseEnv -&gt; Expr CoreBndr -&gt; Expr CoreBndr
</span><a href="GHC.Core.Opt.LiberateCase.html#libCase"><span class="hs-identifier hs-var">libCase</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963783"><span class="hs-identifier hs-var">env</span></a></span><span class="hs-special">)</span><span> </span><span class="annot"><span class="annottext">[Expr CoreBndr]
</span><a href="#local-6989586621680963781"><span class="hs-identifier hs-var">args</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-279"></span><span>
</span><span id="line-280"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#freeScruts"><span class="hs-identifier hs-type">freeScruts</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span>
</span><span id="line-281"></span><span>           </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseLevel"><span class="hs-identifier hs-type">LibCaseLevel</span></a></span><span>      </span><span class="hs-comment">-- Level of the recursive Id</span><span>
</span><span id="line-282"></span><span>           </span><span class="hs-glyph">-&gt;</span><span> </span><span class="hs-special">[</span><span class="annot"><a href="GHC.Types.Var.html#Id"><span class="hs-identifier hs-type">Id</span></a></span><span class="hs-special">]</span><span>              </span><span class="hs-comment">-- Ids that are scrutinised between the binding</span><span>
</span><span id="line-283"></span><span>                                </span><span class="hs-comment">-- of the recursive Id and here</span><span>
</span><span id="line-284"></span><span id="freeScruts"><span class="annot"><span class="annottext">freeScruts :: LibCaseEnv -&gt; LibCaseLevel -&gt; [CoreBndr]
</span><a href="GHC.Core.Opt.LiberateCase.html#freeScruts"><span class="hs-identifier hs-var hs-var">freeScruts</span></a></span></span><span> </span><span id="local-6989586621680963772"><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963772"><span class="hs-identifier hs-var">env</span></a></span></span><span> </span><span id="local-6989586621680963771"><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963771"><span class="hs-identifier hs-var">rec_bind_lvl</span></a></span></span><span>
</span><span id="line-285"></span><span>  </span><span class="hs-glyph">=</span><span> </span><span class="hs-special">[</span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963770"><span class="hs-identifier hs-var">v</span></a></span><span> </span><span class="hs-glyph">|</span><span> </span><span class="hs-special">(</span><span id="local-6989586621680963770"><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963770"><span class="hs-identifier hs-var">v</span></a></span></span><span class="hs-special">,</span><span> </span><span id="local-6989586621680963769"><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963769"><span class="hs-identifier hs-var">scrut_bind_lvl</span></a></span></span><span class="hs-special">,</span><span> </span><span id="local-6989586621680963768"><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963768"><span class="hs-identifier hs-var">scrut_at_lvl</span></a></span></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">&lt;-</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; [(CoreBndr, LibCaseLevel, LibCaseLevel)]
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_scruts"><span class="hs-identifier hs-var hs-var">lc_scruts</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963772"><span class="hs-identifier hs-var">env</span></a></span><span>
</span><span id="line-286"></span><span>       </span><span class="hs-special">,</span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963769"><span class="hs-identifier hs-var">scrut_bind_lvl</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseLevel -&gt; LibCaseLevel -&gt; Bool
forall a. Ord a =&gt; a -&gt; a -&gt; Bool
</span><span class="hs-operator hs-var">&lt;=</span></span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963771"><span class="hs-identifier hs-var">rec_bind_lvl</span></a></span><span>
</span><span id="line-287"></span><span>       </span><span class="hs-special">,</span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963768"><span class="hs-identifier hs-var">scrut_at_lvl</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseLevel -&gt; LibCaseLevel -&gt; Bool
forall a. Ord a =&gt; a -&gt; a -&gt; Bool
</span><span class="hs-operator hs-var">&gt;</span></span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963771"><span class="hs-identifier hs-var">rec_bind_lvl</span></a></span><span class="hs-special">]</span><span>
</span><span id="line-288"></span><span>        </span><span class="hs-comment">-- Note [When to specialise]</span><span>
</span><span id="line-289"></span><span>        </span><span class="hs-comment">-- Note [Avoiding fruitless liberate-case]</span><span>
</span><span id="line-290"></span><span>
</span><span id="line-291"></span><span class="hs-comment">{-
Note [When to specialise]
~~~~~~~~~~~~~~~~~~~~~~~~~
Consider
  f = \x. letrec g = \y. case x of
                           True  -&gt; ... (f a) ...
                           False -&gt; ... (g b) ...

We get the following levels
          f  0
          x  1
          g  1
          y  2

Then 'x' is being scrutinised at a deeper level than its binding, so
it's added to lc_sruts:  [(x,1)]

We do *not* want to specialise the call to 'f', because 'x' is not free
in 'f'.  So here the bind-level of 'x' (=1) is not &lt;= the bind-level of 'f' (=0).

We *do* want to specialise the call to 'g', because 'x' is free in g.
Here the bind-level of 'x' (=1) is &lt;= the bind-level of 'g' (=1).

Note [Avoiding fruitless liberate-case]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider also:
  f = \x. case top_lvl_thing of
                I# _ -&gt; let g = \y. ... g ...
                        in ...

Here, top_lvl_thing is scrutinised at a level (1) deeper than its
binding site (0).  Nevertheless, we do NOT want to specialise the call
to 'g' because all the structure in its free variables is already
visible at the definition site for g.  Hence, when considering specialising
an occurrence of 'g', we want to check that there's a scruted-var v st

   a) v's binding site is *outside* g
   b) v's scrutinisation site is *inside* g


************************************************************************
*                                                                      *
        Utility functions
*                                                                      *
************************************************************************
-}</span><span>
</span><span id="line-337"></span><span>
</span><span id="line-338"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#addBinders"><span class="hs-identifier hs-type">addBinders</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="hs-special">[</span><span class="annot"><a href="GHC.Core.html#CoreBndr"><span class="hs-identifier hs-type">CoreBndr</span></a></span><span class="hs-special">]</span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span>
</span><span id="line-339"></span><span id="addBinders"><span class="annot"><span class="annottext">addBinders :: LibCaseEnv -&gt; [CoreBndr] -&gt; LibCaseEnv
</span><a href="GHC.Core.Opt.LiberateCase.html#addBinders"><span class="hs-identifier hs-var hs-var">addBinders</span></a></span></span><span> </span><span id="local-6989586621680963765"><span class="annot"><span class="annottext">env :: LibCaseEnv
</span><a href="#local-6989586621680963765"><span class="hs-identifier hs-var">env</span></a></span></span><span class="hs-glyph">@</span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span> </span><span class="hs-special">{</span><span> </span><span class="annot"><span class="annottext">lc_lvl :: LibCaseEnv -&gt; LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_lvl"><span class="hs-identifier hs-var">lc_lvl</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span id="local-6989586621680963762"><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963762"><span class="hs-identifier hs-var">lvl</span></a></span></span><span class="hs-special">,</span><span> </span><span class="annot"><span class="annottext">lc_lvl_env :: LibCaseEnv -&gt; IdEnv LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_lvl_env"><span class="hs-identifier hs-var">lc_lvl_env</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span id="local-6989586621680963760"><span class="annot"><span class="annottext">IdEnv LibCaseLevel
</span><a href="#local-6989586621680963760"><span class="hs-identifier hs-var">lvl_env</span></a></span></span><span> </span><span class="hs-special">}</span><span class="hs-special">)</span><span> </span><span id="local-6989586621680963759"><span class="annot"><span class="annottext">[CoreBndr]
</span><a href="#local-6989586621680963759"><span class="hs-identifier hs-var">binders</span></a></span></span><span>
</span><span id="line-340"></span><span>  </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963765"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="hs-special">{</span><span> </span><span class="annot"><span class="annottext">lc_lvl_env :: IdEnv LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_lvl_env"><span class="hs-identifier hs-var">lc_lvl_env</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">IdEnv LibCaseLevel
</span><a href="#local-6989586621680963758"><span class="hs-identifier hs-var">lvl_env'</span></a></span><span> </span><span class="hs-special">}</span><span>
</span><span id="line-341"></span><span>  </span><span class="hs-keyword">where</span><span>
</span><span id="line-342"></span><span>    </span><span id="local-6989586621680963758"><span class="annot"><span class="annottext">lvl_env' :: IdEnv LibCaseLevel
</span><a href="#local-6989586621680963758"><span class="hs-identifier hs-var hs-var">lvl_env'</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">IdEnv LibCaseLevel
-&gt; [(CoreBndr, LibCaseLevel)] -&gt; IdEnv LibCaseLevel
forall a. VarEnv a -&gt; [(CoreBndr, a)] -&gt; VarEnv a
</span><a href="GHC.Types.Var.Env.html#extendVarEnvList"><span class="hs-identifier hs-var">extendVarEnvList</span></a></span><span> </span><span class="annot"><span class="annottext">IdEnv LibCaseLevel
</span><a href="#local-6989586621680963760"><span class="hs-identifier hs-var">lvl_env</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">[CoreBndr]
</span><a href="#local-6989586621680963759"><span class="hs-identifier hs-var">binders</span></a></span><span> </span><span class="annot"><span class="annottext">[CoreBndr] -&gt; [LibCaseLevel] -&gt; [(CoreBndr, LibCaseLevel)]
forall a b. [a] -&gt; [b] -&gt; [(a, b)]
</span><a href="../../base/src/GHC.List.html#zip"><span class="hs-operator hs-var">`zip`</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseLevel -&gt; [LibCaseLevel]
forall a. a -&gt; [a]
</span><a href="../../base/src/GHC.List.html#repeat"><span class="hs-identifier hs-var">repeat</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963762"><span class="hs-identifier hs-var">lvl</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-343"></span><span>
</span><span id="line-344"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#addRecBinds"><span class="hs-identifier hs-type">addRecBinds</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="hs-special">[</span><span class="hs-special">(</span><span class="annot"><a href="GHC.Types.Var.html#Id"><span class="hs-identifier hs-type">Id</span></a></span><span class="hs-special">,</span><span class="annot"><a href="GHC.Core.html#CoreExpr"><span class="hs-identifier hs-type">CoreExpr</span></a></span><span class="hs-special">)</span><span class="hs-special">]</span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span>
</span><span id="line-345"></span><span id="addRecBinds"><span class="annot"><span class="annottext">addRecBinds :: LibCaseEnv -&gt; [(CoreBndr, Expr CoreBndr)] -&gt; LibCaseEnv
</span><a href="GHC.Core.Opt.LiberateCase.html#addRecBinds"><span class="hs-identifier hs-var hs-var">addRecBinds</span></a></span></span><span> </span><span id="local-6989586621680963755"><span class="annot"><span class="annottext">env :: LibCaseEnv
</span><a href="#local-6989586621680963755"><span class="hs-identifier hs-var">env</span></a></span></span><span class="hs-glyph">@</span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span> </span><span class="hs-special">{</span><span class="annot"><span class="annottext">lc_lvl :: LibCaseEnv -&gt; LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_lvl"><span class="hs-identifier hs-var">lc_lvl</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span id="local-6989586621680963754"><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963754"><span class="hs-identifier hs-var">lvl</span></a></span></span><span class="hs-special">,</span><span> </span><span class="annot"><span class="annottext">lc_lvl_env :: LibCaseEnv -&gt; IdEnv LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_lvl_env"><span class="hs-identifier hs-var">lc_lvl_env</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span id="local-6989586621680963753"><span class="annot"><span class="annottext">IdEnv LibCaseLevel
</span><a href="#local-6989586621680963753"><span class="hs-identifier hs-var">lvl_env</span></a></span></span><span class="hs-special">,</span><span>
</span><span id="line-346"></span><span>                             </span><span class="annot"><span class="annottext">lc_rec_env :: LibCaseEnv -&gt; IdEnv CoreBind
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_rec_env"><span class="hs-identifier hs-var">lc_rec_env</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span id="local-6989586621680963751"><span class="annot"><span class="annottext">IdEnv CoreBind
</span><a href="#local-6989586621680963751"><span class="hs-identifier hs-var">rec_env</span></a></span></span><span class="hs-special">}</span><span class="hs-special">)</span><span> </span><span id="local-6989586621680963750"><span class="annot"><span class="annottext">[(CoreBndr, Expr CoreBndr)]
</span><a href="#local-6989586621680963750"><span class="hs-identifier hs-var">pairs</span></a></span></span><span>
</span><span id="line-347"></span><span>  </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963755"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="hs-special">{</span><span> </span><span class="annot"><span class="annottext">lc_lvl :: LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_lvl"><span class="hs-identifier hs-var">lc_lvl</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963749"><span class="hs-identifier hs-var">lvl'</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><span class="annottext">lc_lvl_env :: IdEnv LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_lvl_env"><span class="hs-identifier hs-var">lc_lvl_env</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">IdEnv LibCaseLevel
</span><a href="#local-6989586621680963748"><span class="hs-identifier hs-var">lvl_env'</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><span class="annottext">lc_rec_env :: IdEnv CoreBind
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_rec_env"><span class="hs-identifier hs-var">lc_rec_env</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">IdEnv CoreBind
</span><a href="#local-6989586621680963747"><span class="hs-identifier hs-var">rec_env'</span></a></span><span> </span><span class="hs-special">}</span><span>
</span><span id="line-348"></span><span>  </span><span class="hs-keyword">where</span><span>
</span><span id="line-349"></span><span>    </span><span id="local-6989586621680963749"><span class="annot"><span class="annottext">lvl' :: LibCaseLevel
</span><a href="#local-6989586621680963749"><span class="hs-identifier hs-var hs-var">lvl'</span></a></span></span><span>     </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963754"><span class="hs-identifier hs-var">lvl</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseLevel -&gt; LibCaseLevel -&gt; LibCaseLevel
forall a. Num a =&gt; a -&gt; a -&gt; a
</span><a href="../../base/src/GHC.Num.html#%2B"><span class="hs-operator hs-var">+</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><span class="hs-number">1</span></span><span>
</span><span id="line-350"></span><span>    </span><span id="local-6989586621680963748"><span class="annot"><span class="annottext">lvl_env' :: IdEnv LibCaseLevel
</span><a href="#local-6989586621680963748"><span class="hs-identifier hs-var hs-var">lvl_env'</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">IdEnv LibCaseLevel
-&gt; [(CoreBndr, LibCaseLevel)] -&gt; IdEnv LibCaseLevel
forall a. VarEnv a -&gt; [(CoreBndr, a)] -&gt; VarEnv a
</span><a href="GHC.Types.Var.Env.html#extendVarEnvList"><span class="hs-identifier hs-var">extendVarEnvList</span></a></span><span> </span><span class="annot"><span class="annottext">IdEnv LibCaseLevel
</span><a href="#local-6989586621680963753"><span class="hs-identifier hs-var">lvl_env</span></a></span><span> </span><span class="hs-special">[</span><span class="hs-special">(</span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963743"><span class="hs-identifier hs-var">binder</span></a></span><span class="hs-special">,</span><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963754"><span class="hs-identifier hs-var">lvl</span></a></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">|</span><span> </span><span class="hs-special">(</span><span id="local-6989586621680963743"><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963743"><span class="hs-identifier hs-var">binder</span></a></span></span><span class="hs-special">,</span><span class="annot"><span class="annottext">Expr CoreBndr
</span><span class="hs-identifier">_</span></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">&lt;-</span><span> </span><span class="annot"><span class="annottext">[(CoreBndr, Expr CoreBndr)]
</span><a href="#local-6989586621680963750"><span class="hs-identifier hs-var">pairs</span></a></span><span class="hs-special">]</span><span>
</span><span id="line-351"></span><span>    </span><span id="local-6989586621680963747"><span class="annot"><span class="annottext">rec_env' :: IdEnv CoreBind
</span><a href="#local-6989586621680963747"><span class="hs-identifier hs-var hs-var">rec_env'</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">IdEnv CoreBind -&gt; [(CoreBndr, CoreBind)] -&gt; IdEnv CoreBind
forall a. VarEnv a -&gt; [(CoreBndr, a)] -&gt; VarEnv a
</span><a href="GHC.Types.Var.Env.html#extendVarEnvList"><span class="hs-identifier hs-var">extendVarEnvList</span></a></span><span> </span><span class="annot"><span class="annottext">IdEnv CoreBind
</span><a href="#local-6989586621680963751"><span class="hs-identifier hs-var">rec_env</span></a></span><span> </span><span class="hs-special">[</span><span class="hs-special">(</span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963742"><span class="hs-identifier hs-var">binder</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><span class="annottext">[(CoreBndr, Expr CoreBndr)] -&gt; CoreBind
forall b. [(b, Expr b)] -&gt; Bind b
</span><a href="GHC.Core.html#Rec"><span class="hs-identifier hs-var">Rec</span></a></span><span> </span><span class="annot"><span class="annottext">[(CoreBndr, Expr CoreBndr)]
</span><a href="#local-6989586621680963750"><span class="hs-identifier hs-var">pairs</span></a></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">|</span><span> </span><span class="hs-special">(</span><span id="local-6989586621680963742"><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963742"><span class="hs-identifier hs-var">binder</span></a></span></span><span class="hs-special">,</span><span class="annot"><span class="annottext">Expr CoreBndr
</span><span class="hs-identifier">_</span></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">&lt;-</span><span> </span><span class="annot"><span class="annottext">[(CoreBndr, Expr CoreBndr)]
</span><a href="#local-6989586621680963750"><span class="hs-identifier hs-var">pairs</span></a></span><span class="hs-special">]</span><span>
</span><span id="line-352"></span><span>
</span><span id="line-353"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#addScrutedVar"><span class="hs-identifier hs-type">addScrutedVar</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span>
</span><span id="line-354"></span><span>              </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="GHC.Types.Var.html#Id"><span class="hs-identifier hs-type">Id</span></a></span><span>             </span><span class="hs-comment">-- This Id is being scrutinised by a case expression</span><span>
</span><span id="line-355"></span><span>              </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span>
</span><span id="line-356"></span><span>
</span><span id="line-357"></span><span id="addScrutedVar"><span class="annot"><span class="annottext">addScrutedVar :: LibCaseEnv -&gt; CoreBndr -&gt; LibCaseEnv
</span><a href="GHC.Core.Opt.LiberateCase.html#addScrutedVar"><span class="hs-identifier hs-var hs-var">addScrutedVar</span></a></span></span><span> </span><span id="local-6989586621680963741"><span class="annot"><span class="annottext">env :: LibCaseEnv
</span><a href="#local-6989586621680963741"><span class="hs-identifier hs-var">env</span></a></span></span><span class="hs-glyph">@</span><span class="hs-special">(</span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span> </span><span class="hs-special">{</span><span> </span><span class="annot"><span class="annottext">lc_lvl :: LibCaseEnv -&gt; LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_lvl"><span class="hs-identifier hs-var">lc_lvl</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span id="local-6989586621680963740"><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963740"><span class="hs-identifier hs-var">lvl</span></a></span></span><span class="hs-special">,</span><span> </span><span class="annot"><span class="annottext">lc_lvl_env :: LibCaseEnv -&gt; IdEnv LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_lvl_env"><span class="hs-identifier hs-var">lc_lvl_env</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span id="local-6989586621680963739"><span class="annot"><span class="annottext">IdEnv LibCaseLevel
</span><a href="#local-6989586621680963739"><span class="hs-identifier hs-var">lvl_env</span></a></span></span><span class="hs-special">,</span><span>
</span><span id="line-358"></span><span>                                </span><span class="annot"><span class="annottext">lc_scruts :: LibCaseEnv -&gt; [(CoreBndr, LibCaseLevel, LibCaseLevel)]
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_scruts"><span class="hs-identifier hs-var">lc_scruts</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span id="local-6989586621680963738"><span class="annot"><span class="annottext">[(CoreBndr, LibCaseLevel, LibCaseLevel)]
</span><a href="#local-6989586621680963738"><span class="hs-identifier hs-var">scruts</span></a></span></span><span> </span><span class="hs-special">}</span><span class="hs-special">)</span><span> </span><span id="local-6989586621680963737"><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963737"><span class="hs-identifier hs-var">scrut_var</span></a></span></span><span>
</span><span id="line-359"></span><span>  </span><span class="hs-glyph">|</span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963736"><span class="hs-identifier hs-var">bind_lvl</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseLevel -&gt; LibCaseLevel -&gt; Bool
forall a. Ord a =&gt; a -&gt; a -&gt; Bool
</span><span class="hs-operator hs-var">&lt;</span></span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963740"><span class="hs-identifier hs-var">lvl</span></a></span><span>
</span><span id="line-360"></span><span>  </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963741"><span class="hs-identifier hs-var">env</span></a></span><span> </span><span class="hs-special">{</span><span> </span><span class="annot"><span class="annottext">lc_scruts :: [(CoreBndr, LibCaseLevel, LibCaseLevel)]
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_scruts"><span class="hs-identifier hs-var">lc_scruts</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">[(CoreBndr, LibCaseLevel, LibCaseLevel)]
</span><a href="#local-6989586621680963734"><span class="hs-identifier hs-var">scruts'</span></a></span><span> </span><span class="hs-special">}</span><span>
</span><span id="line-361"></span><span>        </span><span class="hs-comment">-- Add to scruts iff the scrut_var is being scrutinised at</span><span>
</span><span id="line-362"></span><span>        </span><span class="hs-comment">-- a deeper level than its defn</span><span>
</span><span id="line-363"></span><span>
</span><span id="line-364"></span><span>  </span><span class="hs-glyph">|</span><span> </span><span class="annot"><span class="annottext">Bool
</span><a href="../../base/src/GHC.Base.html#otherwise"><span class="hs-identifier hs-var">otherwise</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963741"><span class="hs-identifier hs-var">env</span></a></span><span>
</span><span id="line-365"></span><span>  </span><span class="hs-keyword">where</span><span>
</span><span id="line-366"></span><span>    </span><span id="local-6989586621680963734"><span class="annot"><span class="annottext">scruts' :: [(CoreBndr, LibCaseLevel, LibCaseLevel)]
</span><a href="#local-6989586621680963734"><span class="hs-identifier hs-var hs-var">scruts'</span></a></span></span><span>  </span><span class="hs-glyph">=</span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963737"><span class="hs-identifier hs-var">scrut_var</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963736"><span class="hs-identifier hs-var">bind_lvl</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963740"><span class="hs-identifier hs-var">lvl</span></a></span><span class="hs-special">)</span><span> </span><span class="annot"><span class="annottext">(CoreBndr, LibCaseLevel, LibCaseLevel)
-&gt; [(CoreBndr, LibCaseLevel, LibCaseLevel)]
-&gt; [(CoreBndr, LibCaseLevel, LibCaseLevel)]
forall a. a -&gt; [a] -&gt; [a]
</span><span class="hs-glyph hs-var">:</span></span><span> </span><span class="annot"><span class="annottext">[(CoreBndr, LibCaseLevel, LibCaseLevel)]
</span><a href="#local-6989586621680963738"><span class="hs-identifier hs-var">scruts</span></a></span><span>
</span><span id="line-367"></span><span>    </span><span id="local-6989586621680963736"><span class="annot"><span class="annottext">bind_lvl :: LibCaseLevel
</span><a href="#local-6989586621680963736"><span class="hs-identifier hs-var hs-var">bind_lvl</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="hs-keyword">case</span><span> </span><span class="annot"><span class="annottext">IdEnv LibCaseLevel -&gt; CoreBndr -&gt; Maybe LibCaseLevel
forall a. VarEnv a -&gt; CoreBndr -&gt; Maybe a
</span><a href="GHC.Types.Var.Env.html#lookupVarEnv"><span class="hs-identifier hs-var">lookupVarEnv</span></a></span><span> </span><span class="annot"><span class="annottext">IdEnv LibCaseLevel
</span><a href="#local-6989586621680963739"><span class="hs-identifier hs-var">lvl_env</span></a></span><span> </span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963737"><span class="hs-identifier hs-var">scrut_var</span></a></span><span> </span><span class="hs-keyword">of</span><span>
</span><span id="line-368"></span><span>                 </span><span class="annot"><a href="../../base/src/GHC.Maybe.html#Just"><span class="hs-identifier hs-type">Just</span></a></span><span> </span><span id="local-6989586621680963732"><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963732"><span class="hs-identifier hs-var">lvl</span></a></span></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963732"><span class="hs-identifier hs-var">lvl</span></a></span><span>
</span><span id="line-369"></span><span>                 </span><span class="annot"><span class="annottext">Maybe LibCaseLevel
</span><a href="../../base/src/GHC.Maybe.html#Nothing"><span class="hs-identifier hs-var">Nothing</span></a></span><span>  </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#topLevel"><span class="hs-identifier hs-var">topLevel</span></a></span><span>
</span><span id="line-370"></span><span>
</span><span id="line-371"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#lookupRecId"><span class="hs-identifier hs-type">lookupRecId</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="GHC.Types.Var.html#Id"><span class="hs-identifier hs-type">Id</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="../../base/src/GHC.Maybe.html#Maybe"><span class="hs-identifier hs-type">Maybe</span></a></span><span> </span><span class="annot"><a href="GHC.Core.html#CoreBind"><span class="hs-identifier hs-type">CoreBind</span></a></span><span>
</span><span id="line-372"></span><span id="lookupRecId"><span class="annot"><span class="annottext">lookupRecId :: LibCaseEnv -&gt; CoreBndr -&gt; Maybe CoreBind
</span><a href="GHC.Core.Opt.LiberateCase.html#lookupRecId"><span class="hs-identifier hs-var hs-var">lookupRecId</span></a></span></span><span> </span><span id="local-6989586621680963730"><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963730"><span class="hs-identifier hs-var">env</span></a></span></span><span> </span><span id="local-6989586621680963729"><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963729"><span class="hs-identifier hs-var">id</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">IdEnv CoreBind -&gt; CoreBndr -&gt; Maybe CoreBind
forall a. VarEnv a -&gt; CoreBndr -&gt; Maybe a
</span><a href="GHC.Types.Var.Env.html#lookupVarEnv"><span class="hs-identifier hs-var">lookupVarEnv</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">LibCaseEnv -&gt; IdEnv CoreBind
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_rec_env"><span class="hs-identifier hs-var hs-var">lc_rec_env</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963730"><span class="hs-identifier hs-var">env</span></a></span><span class="hs-special">)</span><span> </span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963729"><span class="hs-identifier hs-var">id</span></a></span><span>
</span><span id="line-373"></span><span>
</span><span id="line-374"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#lookupLevel"><span class="hs-identifier hs-type">lookupLevel</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="GHC.Types.Var.html#Id"><span class="hs-identifier hs-type">Id</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseLevel"><span class="hs-identifier hs-type">LibCaseLevel</span></a></span><span>
</span><span id="line-375"></span><span id="lookupLevel"><span class="annot"><span class="annottext">lookupLevel :: LibCaseEnv -&gt; CoreBndr -&gt; LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#lookupLevel"><span class="hs-identifier hs-var hs-var">lookupLevel</span></a></span></span><span> </span><span id="local-6989586621680963728"><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963728"><span class="hs-identifier hs-var">env</span></a></span></span><span> </span><span id="local-6989586621680963727"><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963727"><span class="hs-identifier hs-var">id</span></a></span></span><span>
</span><span id="line-376"></span><span>  </span><span class="hs-glyph">=</span><span> </span><span class="hs-keyword">case</span><span> </span><span class="annot"><span class="annottext">IdEnv LibCaseLevel -&gt; CoreBndr -&gt; Maybe LibCaseLevel
forall a. VarEnv a -&gt; CoreBndr -&gt; Maybe a
</span><a href="GHC.Types.Var.Env.html#lookupVarEnv"><span class="hs-identifier hs-var">lookupVarEnv</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">LibCaseEnv -&gt; IdEnv LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_lvl_env"><span class="hs-identifier hs-var hs-var">lc_lvl_env</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv
</span><a href="#local-6989586621680963728"><span class="hs-identifier hs-var">env</span></a></span><span class="hs-special">)</span><span> </span><span class="annot"><span class="annottext">CoreBndr
</span><a href="#local-6989586621680963727"><span class="hs-identifier hs-var">id</span></a></span><span> </span><span class="hs-keyword">of</span><span>
</span><span id="line-377"></span><span>      </span><span class="annot"><a href="../../base/src/GHC.Maybe.html#Just"><span class="hs-identifier hs-type">Just</span></a></span><span> </span><span id="local-6989586621680963726"><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963726"><span class="hs-identifier hs-var">lvl</span></a></span></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="#local-6989586621680963726"><span class="hs-identifier hs-var">lvl</span></a></span><span>
</span><span id="line-378"></span><span>      </span><span class="annot"><span class="annottext">Maybe LibCaseLevel
</span><a href="../../base/src/GHC.Maybe.html#Nothing"><span class="hs-identifier hs-var">Nothing</span></a></span><span>  </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#topLevel"><span class="hs-identifier hs-var">topLevel</span></a></span><span>
</span><span id="line-379"></span><span>
</span><span id="line-380"></span><span class="hs-comment">{-
************************************************************************
*                                                                      *
         The environment
*                                                                      *
************************************************************************
-}</span><span>
</span><span id="line-387"></span><span>
</span><span id="line-388"></span><span class="hs-keyword">type</span><span> </span><span id="LibCaseLevel"><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseLevel"><span class="hs-identifier hs-var">LibCaseLevel</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="hs-identifier hs-type">Int</span></span><span>
</span><span id="line-389"></span><span>
</span><span id="line-390"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#topLevel"><span class="hs-identifier hs-type">topLevel</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseLevel"><span class="hs-identifier hs-type">LibCaseLevel</span></a></span><span>
</span><span id="line-391"></span><span id="topLevel"><span class="annot"><span class="annottext">topLevel :: LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#topLevel"><span class="hs-identifier hs-var hs-var">topLevel</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><span class="hs-number">0</span></span><span>
</span><span id="line-392"></span><span>
</span><span id="line-393"></span><span class="hs-keyword">data</span><span> </span><span id="LibCaseEnv"><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-var">LibCaseEnv</span></a></span></span><span>
</span><span id="line-394"></span><span>  </span><span class="hs-glyph">=</span><span> </span><span id="LibCaseEnv"><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-var">LibCaseEnv</span></a></span></span><span> </span><span class="hs-special">{</span><span>
</span><span id="line-395"></span><span>        </span><span id="lc_dflags"><span class="annot"><span class="annottext">LibCaseEnv -&gt; DynFlags
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_dflags"><span class="hs-identifier hs-var hs-var">lc_dflags</span></a></span></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.Driver.Session.html#DynFlags"><span class="hs-identifier hs-type">DynFlags</span></a></span><span class="hs-special">,</span><span>
</span><span id="line-396"></span><span>
</span><span id="line-397"></span><span>        </span><span id="lc_lvl"><span class="annot"><span class="annottext">LibCaseEnv -&gt; LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_lvl"><span class="hs-identifier hs-var hs-var">lc_lvl</span></a></span></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseLevel"><span class="hs-identifier hs-type">LibCaseLevel</span></a></span><span class="hs-special">,</span><span> </span><span class="hs-comment">-- Current level</span><span>
</span><span id="line-398"></span><span>                </span><span class="hs-comment">-- The level is incremented when (and only when) going</span><span>
</span><span id="line-399"></span><span>                </span><span class="hs-comment">-- inside the RHS of a (sufficiently small) recursive</span><span>
</span><span id="line-400"></span><span>                </span><span class="hs-comment">-- function.</span><span>
</span><span id="line-401"></span><span>
</span><span id="line-402"></span><span>        </span><span id="lc_lvl_env"><span class="annot"><span class="annottext">LibCaseEnv -&gt; IdEnv LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_lvl_env"><span class="hs-identifier hs-var hs-var">lc_lvl_env</span></a></span></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.Types.Var.Env.html#IdEnv"><span class="hs-identifier hs-type">IdEnv</span></a></span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseLevel"><span class="hs-identifier hs-type">LibCaseLevel</span></a></span><span class="hs-special">,</span><span>
</span><span id="line-403"></span><span>                </span><span class="hs-comment">-- Binds all non-top-level in-scope Ids (top-level and</span><span>
</span><span id="line-404"></span><span>                </span><span class="hs-comment">-- imported things have a level of zero)</span><span>
</span><span id="line-405"></span><span>
</span><span id="line-406"></span><span>        </span><span id="lc_rec_env"><span class="annot"><span class="annottext">LibCaseEnv -&gt; IdEnv CoreBind
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_rec_env"><span class="hs-identifier hs-var hs-var">lc_rec_env</span></a></span></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.Types.Var.Env.html#IdEnv"><span class="hs-identifier hs-type">IdEnv</span></a></span><span> </span><span class="annot"><a href="GHC.Core.html#CoreBind"><span class="hs-identifier hs-type">CoreBind</span></a></span><span class="hs-special">,</span><span>
</span><span id="line-407"></span><span>                </span><span class="hs-comment">-- Binds *only* recursively defined ids, to their own</span><span>
</span><span id="line-408"></span><span>                </span><span class="hs-comment">-- binding group, and *only* in their own RHSs</span><span>
</span><span id="line-409"></span><span>
</span><span id="line-410"></span><span>        </span><span id="lc_scruts"><span class="annot"><span class="annottext">LibCaseEnv -&gt; [(CoreBndr, LibCaseLevel, LibCaseLevel)]
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_scruts"><span class="hs-identifier hs-var hs-var">lc_scruts</span></a></span></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="hs-special">[</span><span class="hs-special">(</span><span class="annot"><a href="GHC.Types.Var.html#Id"><span class="hs-identifier hs-type">Id</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseLevel"><span class="hs-identifier hs-type">LibCaseLevel</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseLevel"><span class="hs-identifier hs-type">LibCaseLevel</span></a></span><span class="hs-special">)</span><span class="hs-special">]</span><span>
</span><span id="line-411"></span><span>                </span><span class="hs-comment">-- Each of these Ids was scrutinised by an enclosing</span><span>
</span><span id="line-412"></span><span>                </span><span class="hs-comment">-- case expression, at a level deeper than its binding</span><span>
</span><span id="line-413"></span><span>                </span><span class="hs-comment">-- level.</span><span>
</span><span id="line-414"></span><span>                </span><span class="hs-comment">--</span><span>
</span><span id="line-415"></span><span>                </span><span class="hs-comment">-- The first LibCaseLevel is the *binding level* of</span><span>
</span><span id="line-416"></span><span>                </span><span class="hs-comment">--   the scrutinised Id,</span><span>
</span><span id="line-417"></span><span>                </span><span class="hs-comment">-- The second is the level *at which it was scrutinised*.</span><span>
</span><span id="line-418"></span><span>                </span><span class="hs-comment">--   (see Note [Avoiding fruitless liberate-case])</span><span>
</span><span id="line-419"></span><span>                </span><span class="hs-comment">-- The former is a bit redundant, since you could always</span><span>
</span><span id="line-420"></span><span>                </span><span class="hs-comment">-- look it up in lc_lvl_env, but it's just cached here</span><span>
</span><span id="line-421"></span><span>                </span><span class="hs-comment">--</span><span>
</span><span id="line-422"></span><span>                </span><span class="hs-comment">-- The order is insignificant; it's a bag really</span><span>
</span><span id="line-423"></span><span>                </span><span class="hs-comment">--</span><span>
</span><span id="line-424"></span><span>                </span><span class="hs-comment">-- There's one element per scrutinisation;</span><span>
</span><span id="line-425"></span><span>                </span><span class="hs-comment">--    in principle the same Id may appear multiple times,</span><span>
</span><span id="line-426"></span><span>                </span><span class="hs-comment">--    although that'd be unusual:</span><span>
</span><span id="line-427"></span><span>                </span><span class="hs-comment">--       case x of { (a,b) -&gt; ....(case x of ...) .. }</span><span>
</span><span id="line-428"></span><span>        </span><span class="hs-special">}</span><span>
</span><span id="line-429"></span><span>
</span><span id="line-430"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#initEnv"><span class="hs-identifier hs-type">initEnv</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.Driver.Session.html#DynFlags"><span class="hs-identifier hs-type">DynFlags</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span>
</span><span id="line-431"></span><span id="initEnv"><span class="annot"><span class="annottext">initEnv :: DynFlags -&gt; LibCaseEnv
</span><a href="GHC.Core.Opt.LiberateCase.html#initEnv"><span class="hs-identifier hs-var hs-var">initEnv</span></a></span></span><span> </span><span id="local-6989586621680963725"><span class="annot"><span class="annottext">DynFlags
</span><a href="#local-6989586621680963725"><span class="hs-identifier hs-var">dflags</span></a></span></span><span>
</span><span id="line-432"></span><span>  </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseEnv :: DynFlags
-&gt; LibCaseLevel
-&gt; IdEnv LibCaseLevel
-&gt; IdEnv CoreBind
-&gt; [(CoreBndr, LibCaseLevel, LibCaseLevel)]
-&gt; LibCaseEnv
</span><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span> </span><span class="hs-special">{</span><span> </span><span class="annot"><span class="annottext">lc_dflags :: DynFlags
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_dflags"><span class="hs-identifier hs-var">lc_dflags</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">DynFlags
</span><a href="#local-6989586621680963725"><span class="hs-identifier hs-var">dflags</span></a></span><span class="hs-special">,</span><span>
</span><span id="line-433"></span><span>                 </span><span class="annot"><span class="annottext">lc_lvl :: LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_lvl"><span class="hs-identifier hs-var">lc_lvl</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">LibCaseLevel
</span><span class="hs-number">0</span></span><span class="hs-special">,</span><span>
</span><span id="line-434"></span><span>                 </span><span class="annot"><span class="annottext">lc_lvl_env :: IdEnv LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_lvl_env"><span class="hs-identifier hs-var">lc_lvl_env</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">IdEnv LibCaseLevel
forall a. VarEnv a
</span><a href="GHC.Types.Var.Env.html#emptyVarEnv"><span class="hs-identifier hs-var">emptyVarEnv</span></a></span><span class="hs-special">,</span><span>
</span><span id="line-435"></span><span>                 </span><span class="annot"><span class="annottext">lc_rec_env :: IdEnv CoreBind
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_rec_env"><span class="hs-identifier hs-var">lc_rec_env</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">IdEnv CoreBind
forall a. VarEnv a
</span><a href="GHC.Types.Var.Env.html#emptyVarEnv"><span class="hs-identifier hs-var">emptyVarEnv</span></a></span><span class="hs-special">,</span><span>
</span><span id="line-436"></span><span>                 </span><span class="annot"><span class="annottext">lc_scruts :: [(CoreBndr, LibCaseLevel, LibCaseLevel)]
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_scruts"><span class="hs-identifier hs-var">lc_scruts</span></a></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="hs-special">[</span><span class="hs-special">]</span><span> </span><span class="hs-special">}</span><span>
</span><span id="line-437"></span><span>
</span><span id="line-438"></span><span class="hs-comment">-- Bomb-out size for deciding if</span><span>
</span><span id="line-439"></span><span class="hs-comment">-- potential liberatees are too big.</span><span>
</span><span id="line-440"></span><span class="hs-comment">-- (passed in from cmd-line args)</span><span>
</span><span id="line-441"></span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#bombOutSize"><span class="hs-identifier hs-type">bombOutSize</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.Core.Opt.LiberateCase.html#LibCaseEnv"><span class="hs-identifier hs-type">LibCaseEnv</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="../../base/src/GHC.Maybe.html#Maybe"><span class="hs-identifier hs-type">Maybe</span></a></span><span> </span><span class="annot"><span class="hs-identifier hs-type">Int</span></span><span>
</span><span id="line-442"></span><span id="bombOutSize"><span class="annot"><span class="annottext">bombOutSize :: LibCaseEnv -&gt; Maybe LibCaseLevel
</span><a href="GHC.Core.Opt.LiberateCase.html#bombOutSize"><span class="hs-identifier hs-var hs-var">bombOutSize</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">DynFlags -&gt; Maybe LibCaseLevel
</span><a href="GHC.Driver.Session.html#liberateCaseThreshold"><span class="hs-identifier hs-var hs-var">liberateCaseThreshold</span></a></span><span> </span><span class="annot"><span class="annottext">(DynFlags -&gt; Maybe LibCaseLevel)
-&gt; (LibCaseEnv -&gt; DynFlags) -&gt; LibCaseEnv -&gt; Maybe LibCaseLevel
forall b c a. (b -&gt; c) -&gt; (a -&gt; b) -&gt; a -&gt; c
</span><a href="../../base/src/GHC.Base.html#."><span class="hs-operator hs-var">.</span></a></span><span> </span><span class="annot"><span class="annottext">LibCaseEnv -&gt; DynFlags
</span><a href="GHC.Core.Opt.LiberateCase.html#lc_dflags"><span class="hs-identifier hs-var hs-var">lc_dflags</span></a></span><span>
</span><span id="line-443"></span></pre></body></html>